// --------------------------------------------------------------------------------------------------------------------
// <copyright file="EditTournamentForm.cs" company="Roman '4ux-nbIx' Novitsky">
//   Copyright (c) Roman '4ux-nbIx' Novitsky 2010
// </copyright>
// <summary>
//   Defines the EditTournamentForm type.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace MtgMC
{
  #region Namespace Imports

  using System;
  using System.Collections.Generic;
  using System.ComponentModel;
  using System.Linq;
  using System.Windows.Forms;

  using DataModel;

  #endregion


  /// <summary>
  /// Describes and manipulates the edit tournament form.
  /// </summary>
  public partial class EditTournamentForm : Form
  {
    #region Constants and Fields

    private readonly ApplicationData _applicationData;
    private readonly bool _createNew;
    private readonly Tournament _tournament;

    #endregion


    #region Constructors and Destructors

    /// <summary>
    /// Initializes a new instance of the <see cref="EditTournamentForm"/> class.
    /// </summary>
    /// <param name="applicationData">
    /// The application data.
    /// </param>
    /// <param name="tournament">
    /// The tournament.
    /// </param>
    public EditTournamentForm(ApplicationData applicationData, Tournament tournament)
    {
      _applicationData = applicationData;

      if (tournament != null)
      {
        _tournament = tournament;
      }
      else
      {
        _tournament = new Tournament { Name = "New Tournament" };
        _createNew = true;
      }

      InitializeComponent();

      _matchFormatComboBox.DataSource = MatchFormatExtensions.ValuesList;
      _matchFormatComboBox.SelectedItem = _tournament.MatchFormat;

      _matchTypeComboBox.DataSource = MatchTypeExtensions.ValuesList;
      _matchTypeComboBox.SelectedItem = _tournament.MatchType;

      _titleTextBox.Text = _tournament.Name;

      if (_tournament.Deck == null && _tournament.MatchFormat.IsLimitedFormat())
      {
        _tournament.Deck = new Deck { Format = _tournament.MatchFormat, Name = _tournament.Name + " Deck" };
      }

      _locationComboBox.Initialize(_applicationData.Locations, "Name", _tournament.Location);
      _deckComboBox.Initialize(_applicationData.Player.Decks, "Name", _tournament.Deck);
    }

    #endregion


    #region Methods

    /// <summary>
    /// Raises the <see cref="E:System.Windows.Forms.Form.Closing"/> event.
    /// </summary>
    /// <param name="e">
    /// A <see cref="T:System.ComponentModel.CancelEventArgs"/> that contains the event data.
    /// </param>
    protected override void OnClosing(CancelEventArgs e)
    {
      if (DialogResult == DialogResult.OK)
      {
        if (!ApplyChanges())
        {
          e.Cancel = true;
        }
      }

      base.OnClosing(e);
    }


    private bool ApplyChanges()
    {
      string tournamentName = _titleTextBox.GetText();

      if (string.IsNullOrEmpty(tournamentName)
          || (_createNew && _applicationData.Tournaments.Any(t => t.Name == tournamentName)))
      {
        MessageBox.Show(
          "The tournament name is invalid.", 
          "Error", 
          MessageBoxButtons.OK, 
          MessageBoxIcon.Hand, 
          MessageBoxDefaultButton.Button1);

        return false;
      }

      Location location = _locationComboBox.GetItem(
        _applicationData.Locations, "location name", l => l.Name, name => new Location { Name = name });

      if (location == null)
      {
        return false;
      }

      var format = (MatchFormat)_matchFormatComboBox.SelectedItem;

      Deck deck;

      if (format.IsLimitedFormat() && _tournament.Deck != null
          && !_applicationData.Player.Decks.Contains(_tournament.Deck))
      {
        deck = _tournament.Deck;
      }
      else
      {
        deck = _deckComboBox.GetItem("deck", d => d.Name, name => new Deck { Name = name, Format = format });
      }

      if (deck == null)
      {
        return false;
      }

      _tournament.Name = tournamentName;

      if (_createNew)
      {
        _applicationData.Tournaments.Add(_tournament);
      }

      if (!_applicationData.Locations.Contains(location))
      {
        _applicationData.Locations.Add(location);
      }

      if (!format.IsLimitedFormat() && !_applicationData.Player.Decks.Contains(deck))
      {
        _applicationData.Player.Decks.Add(deck);
      }
      else if (format.IsLimitedFormat())
      {
        deck.Name = _tournament.LimitedDeckName;

        foreach (TournamentOpponentInfo opponentInfo in _tournament.Opponents)
        {
          opponentInfo.Deck.Name = _tournament.LimitedDeckName;
        }
      }

      DateTime endDate = _endDateTimePicker.Value.Date;
      DateTime startDate = _startDateTimePicker.Value.Date;

      _tournament.MatchFormat = format;
      _tournament.MatchType = (MatchType)_matchTypeComboBox.SelectedItem;
      _tournament.Location = location;
      _tournament.Deck = deck;
      _tournament.EndDate = endDate;
      _tournament.StartDate = startDate;

      return true;
    }


    private void CancelMenuItemClick(object sender, EventArgs e)
    {
      DialogResult = DialogResult.Cancel;
    }


    private void MatchFormatComboBoxSelectedIndexChanged(object sender, EventArgs e)
    {
      var selectedItem = (MatchFormat)_matchFormatComboBox.SelectedItem;
      bool isLimitedFormat = selectedItem.IsLimitedFormat();

      _deckComboBox.Enabled = !isLimitedFormat;

      if (isLimitedFormat)
      {
        SetLimitedDeck();
      }
      else
      {
        _deckComboBox.Text = string.Empty;
        _deckComboBox.DataSource = _applicationData.Player.Decks;
      }
    }


    private void OkItemClick(object sender, EventArgs e)
    {
      DialogResult = DialogResult.OK;
    }


    private void SetLimitedDeck()
    {
      var selectedItem = (MatchFormat)_matchFormatComboBox.SelectedItem;
      bool isLimitedFormat = selectedItem.IsLimitedFormat();

      if (!isLimitedFormat)
      {
        return;
      }

      _deckComboBox.DataSource = new List<Deck>();
      _deckComboBox.Text = Tournament.GetLimitedDeckName(_titleTextBox.GetText());
    }


    private void StartDateTimePickerValueChanged(object sender, EventArgs e)
    {
      _endDateTimePicker.MinDate = _startDateTimePicker.Value.Date;
    }


    private void TitleTextBoxTextChanged(object sender, EventArgs e)
    {
      SetLimitedDeck();
    }

    #endregion
  }
}